import pulp

# Global variable to control the optimization direction (True for minimization, False for maximization)
minimize_problem = False

# Global variable to control the variable type (True for integer, False for continuous)
integer_variables = False

# Set up the problem type based on the minimization or maximization flag
# If minimize_problem is True, we minimize the objective function; otherwise, we maximize it.
if minimize_problem:
    prob = pulp.LpProblem("LP_Problem", pulp.LpMinimize)
else:
    prob = pulp.LpProblem("LP_Problem", pulp.LpMaximize)

# Determine the variable category ('Integer' if integer_variables is True, 'Continuous' otherwise)
cat_type = 'Integer' if integer_variables else 'Continuous'

# Define decision variables and their bounds
# x0: Non-negative continuous/integer variable
x0 = pulp.LpVariable('x0', lowBound=0, cat=cat_type)
# x1: Continuous/integer variable between 0 and 6
x1 = pulp.LpVariable('x1', lowBound=0, upBound=6, cat=cat_type)
# x2: Continuous/integer variable greater than or equal to 1
x2 = pulp.LpVariable('x2', lowBound=1, cat=cat_type)
# x3: Continuous/integer variable with a lower bound of -3
x3 = pulp.LpVariable('x3', lowBound=-3, cat=cat_type)

# Define the objective function to be optimized
# The objective is to maximize/minimize 29*x0 + 45*x1
prob += 29 * x0 + 45 * x1, "Objective"

# Define inequality constraints
# Constraint 1: x0 - x1 - 3*x2 <= 5
prob += x0 - x1 - 3 * x2 <= 5, "Constraint_1"
# Constraint 2: -2*x0 + 3*x1 + 7*x2 - 3*x3 <= -10
prob += -2 * x0 + 3 * x1 + 7 * x2 - 3 * x3 <= -10, "Constraint_2"

# Define equality constraints
# Constraint 3: 2*x0 + 8*x1 + x2 = 60
prob += 2 * x0 + 8 * x1 + x2 == 60, "Constraint_3"
# Constraint 4: 4*x0 + 4*x1 + x3 = 60
prob += 4 * x0 + 4 * x1 + x3 == 60, "Constraint_4"

# Solve the linear programming problem
prob.solve()

# Output the solution status, variable values, and the optimal objective value
print("Status:", pulp.LpStatus[prob.status])  # Print the status of the solution (e.g., Optimal, Infeasible)
print("Optimal solution:")
for v in prob.variables():
    print(v.name, "=", v.varValue)  # Print the name and value of each variable in the optimal solution
print("Optimal value:", pulp.value(prob.objective))  # Print the optimal value of the objective function
